package me.monster.lab.androidrforegroundalive

import android.Manifest
import android.app.role.RoleManager
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.provider.Settings
import android.util.Log
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import java.io.File
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors


class MainActivity : AppCompatActivity() {
    private lateinit var viewFinder: PreviewView
    private var imageCapture: ImageCapture? = null

    private lateinit var outputDirectory: File
    private lateinit var cameraExecutor: ExecutorService


    companion object {
        private const val TAG = "CameraXBasic"
        private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
        private const val REQUEST_CODE_PERMISSIONS = 10
        private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Log.d(TAG, "MainActivity onCreate ");

        viewFinder = findViewById(R.id.mainViewFinder)
        outputDirectory = getOutputDirectory()
        cameraExecutor = Executors.newSingleThreadExecutor()

        findViewById<Button>(R.id.btnMainStartService).setOnClickListener {
            Log.d(TAG, "interceptor kill")
            if (Build.VERSION.SDK_INT >= KeepLiveAliveService.SDK_INT_30) {
                KeepLiveAliveService.start(this, 102)
            }
        }

        findViewById<Button>(R.id.btnMainEndService).setOnClickListener {
            if (Build.VERSION.SDK_INT >= KeepLiveAliveService.SDK_INT_30) {
                KeepLiveAliveService.stop(this)
            }
        }

        findViewById<Button>(R.id.btnMainPreview).setOnClickListener {
            previewCamerax()
        }

        findViewById<Button>(R.id.btnMainBack)
            .setOnClickListener {
                afterTimeKillService()
            }

        findViewById<Button>(R.id.btnMainCheckAlertWindow)
            .setOnClickListener {
                checkAlertWindowPermission()
            }

        findViewById<Button>(R.id.btnMainCheckCallScreen)
            .setOnClickListener {
                requestRole()
            }

        findViewById<Button>(R.id.btnMainMediaProjection)
            .setOnClickListener {
                ScreenCaptureImageActivity.start(this)
            }
        findViewById<Button>(R.id.btnMainSettingNotification)
            .setOnClickListener {
                gotoNotificationSettings()
            }
    }

    private fun gotoNotificationSettings() {
        NotificationHelper().checkNotificationChannel(this)
        try {
            val intent = Intent()
            intent.action = Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS
            intent.putExtra(Settings.EXTRA_CHANNEL_ID, NotificationHelper.notification_channel_id)
            intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
            startActivity(intent)
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
            Log.d(TAG, "prepare to go settings ")
            val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
            val uri = Uri.fromParts("package", packageName, null)
            intent.data = uri
            startActivity(intent)
        }
    }

    private val REQUEST_ID = 1

    fun requestRole() {
        val roleManager: RoleManager = getSystemService(ROLE_SERVICE) as RoleManager
        val intent: Intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_SCREENING)
        startActivityForResult(intent, REQUEST_ID)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_ID) {
            if (resultCode == RESULT_OK) {
                // Your app is now the call screening app
                Toast.makeText(this, "cll screening app", Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(this, "not screening app", Toast.LENGTH_SHORT).show()
            }
        }
    }

    private fun checkAlertWindowPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
            AlertDialog.Builder(this)
                .setTitle("暂无权限")
                .setMessage("当前暂无显示在其他应用的上层权限，是否开启？")
                .setPositiveButton("去开启") { _, _ ->
                    val activity = this@MainActivity
                    activity.startActivityForResult(
                        Intent(
                            Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                            Uri.parse("package:" + activity.packageName)
                        ), 0
                    )
                }
                .setNegativeButton("算了吧") { _, _ ->
                    Toast.makeText(this@MainActivity, "您选择了不开启权限", Toast.LENGTH_SHORT).show()
                }
                .create().show()
        } else {
            Toast.makeText(this, "可以创建一个 AlertWindow", Toast.LENGTH_SHORT).show()
        }
    }

    private fun afterTimeKillService() {
        Log.d(TAG, "after 100 second to stop service")
        Handler(Looper.getMainLooper()).postDelayed({
            Log.d(TAG, "prepare to stop service ")
            findViewById<Button>(R.id.btnMainEndService).performClick()
        }, 100 * 1000)
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        if (requestCode == REQUEST_CODE_PERMISSIONS) {
            if (allPermissionsGranted()) {
                startCamera()
            } else {
                Toast.makeText(
                    this,
                    "Permissions not granted by the user.",
                    Toast.LENGTH_SHORT
                ).show()
                finish()
            }
        }
    }

    private fun previewCamerax() {
        if (allPermissionsGranted()) {
            startCamera()
        } else {
            ActivityCompat.requestPermissions(
                this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS
            )
        }
    }

    private fun startCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

        cameraProviderFuture.addListener(Runnable {
            // Used to bind the lifecycle of cameras to the lifecycle owner
            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

            // Preview
            val preview = Preview.Builder()
                .build()
                .also {
                    it.setSurfaceProvider(viewFinder.createSurfaceProvider())
                }

            // Select back camera as a default
            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

            try {
                // Unbind use cases before rebinding
                cameraProvider.unbindAll()

                // Bind use cases to camera
                cameraProvider.bindToLifecycle(
                    this, cameraSelector, preview
                )

            } catch (exc: Exception) {
                Log.e(TAG, "Use case binding failed", exc)
            }

        }, ContextCompat.getMainExecutor(this))
    }


    private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
        ContextCompat.checkSelfPermission(
            baseContext, it
        ) == PackageManager.PERMISSION_GRANTED
    }

    private fun getOutputDirectory(): File {
        val mediaDir = externalMediaDirs.firstOrNull()?.let {
            File(it, resources.getString(R.string.app_name)).apply { mkdirs() }
        }
        return if (mediaDir != null && mediaDir.exists())
            mediaDir else filesDir
    }

}